#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "web_internal.h"
#include "web_login.h"
#include "web_cmd.h"
#include "web_internal.h"
#include "web_log.h"


#include "json_object.h"
#include "json_tokener.h"
#include "json_util.h"
 
void test_jsonc()
{
 
    struct json_object *infor_object = NULL;
    infor_object = json_object_new_object();
    if (NULL == infor_object)
    {
        printf("new json object failed.\n");
        return;
    }
 
    struct json_object *para_object = NULL;
    para_object = json_object_new_object();
    if (NULL == para_object)
    {
        json_object_put(infor_object);//free
        printf("new json object failed.\n");
        return;
    }
 
    struct json_object *array_object = NULL;
    array_object = json_object_new_array();
    if (NULL == array_object)
    {
        json_object_put(infor_object);//free
        json_object_put(para_object);//free
        printf("new json object failed.\n");
        return;
    }
 
    /*添加json值类型到数组中*/
    json_object_array_add(array_object, json_object_new_int(256));
    json_object_array_add(array_object, json_object_new_int(257));
    json_object_array_add(array_object, json_object_new_int(258));
 
    json_object_object_add(para_object, "DeviceId", json_object_new_string("sn_iso_9000"));
    json_object_object_add(para_object, "MacAddr", json_object_new_string("AA:BB:CC:DD:EE:FF"));
    json_object_object_add(para_object, "Visible", json_object_new_int(1));
 
    /*添加json名称和值到json对象集合中*/
    json_object_object_add(infor_object, "method", json_object_new_string("GetSystemInfo"));
    json_object_object_add(infor_object, "param", para_object);
    json_object_object_add(infor_object, "id", json_object_new_string("101"));
 
    /*添加数组集合到json对象中*/
    json_object_object_add(infor_object, "array", array_object);
 
    printf("-----------json infor ---------------------------\n");
    printf("%s\n", json_object_to_json_string(infor_object));
    printf("-----------json infor ---------------------------\n");
 
    struct json_object *result_object = NULL;
 
 
    result_object =  json_object_object_get(infor_object, "method");
    printf("-----------result_object method ---------------------------\n");
    printf("%s\n", json_object_to_json_string(result_object));
    printf("-----------result_object method---------------------------\n");
 
    result_object =  json_object_object_get(infor_object, "param");
    printf("-----------result_object param ---------------------------\n");
    printf("%s\n", json_object_to_json_string(result_object));
    printf("-----------result_object param---------------------------\n");
 
    result_object =  json_object_object_get(infor_object, "array");
    printf("-----------result_object  array---------------------------\n");
    printf("%s\n", json_object_to_json_string(result_object));
    printf("-----------result_object array---------------------------\n");
 
    int i;
    for(i = 0; i < json_object_array_length(result_object); i++) {
      struct json_object *obj = json_object_array_get_idx(result_object, i);
      printf("\t[%d]=%s\n", i, json_object_to_json_string(obj));
    }
 
    json_object_put(infor_object);//free
 
}

static int g_login_id = 0;


 
typedef struct{
    unsigned int size;        //子字符串数量
    char **list;            //用字符串数组来存放字符串列表
}st_strlist;
 
/*
 * 初始化一个字符串列表
 * 注意：strlist_malloc() 和 strlist_free(st_strlist*) 要配对使用
 */
st_strlist* strlist_malloc()
{
    st_strlist *strlist = (st_strlist*)malloc(sizeof(st_strlist));
    memset(strlist, 0, sizeof(st_strlist));
    return strlist;
}
 
/*
 * 在strlist列表的末端增加一个字符串
 */
int strlist_add(st_strlist *strlist, char *str)
{
    int len = strlen(str);
    strlist->size++;
    strlist->list = (char**)realloc(strlist->list, sizeof(char*) * strlist->size);
    if(strlist->list == NULL){
        /* out of memory! */
        printf("error: not enough memory (realloc returned NULL)\n");
        return -1;
    }
    strlist->list[strlist->size-1]=(char*)malloc(len+1);
    memcpy(strlist->list[strlist->size-1], str, len);
    (strlist->list[strlist->size-1])[len]=0;
    return strlist->size;
}
 
/*
 * 在字符串列表的index序号后插入str字符串
 */
int strlist_insertAfter(st_strlist *strlist, char* str, unsigned int index)
{
    int i, len;
    if(index >= strlist->size){
        return -1;
    }
    len = strlen(str);
    strlist->size++;
    strlist->list = (char**)realloc(strlist->list, sizeof(char*) * strlist->size);
    if(strlist->list == NULL){
        /* out of memory! */
        printf("error: not enough memory (realloc returned NULL)\n");
        return -1;
    }
    for(i= strlist->size-1; i>index+1; i--){
        strlist->list[i] = strlist->list[i-1];
    }
    strlist->list[index+1] = (char*)malloc(len+1);
    memcpy(strlist->list[index+1], str, len);
    strlist->list[index+1][len]=0;
    return 0;
}
 
/*
 * 删除字符串列表strlist末端的字符串
 */
int strlist_removeLast(st_strlist *strlist){
    if(strlist->size <=0){
        return -1;
    }
    free(strlist->list[strlist->size-1]);
    strlist->size--;
    return strlist->size;
}
 
/*
 * 删除字符串列表index位置处的字符串
 */
int strlist_removeAt(st_strlist *strlist, unsigned int index)
{
    int i;
    if(index >= strlist->size){
        return -1;
    }
    free(strlist->list[index]);
    for(i=index; i< strlist->size-1; i++){
        strlist->list[i] = strlist->list[i+1];
    }
    strlist->size--;
    return strlist->size;
}
 
/*
 * 获取strlist中index处的字符串。
 */
char* strlist_getStrAt(st_strlist *strlist, unsigned int index)
{
    if(strlist==NULL || index>=strlist->size){
        return NULL;
    }
    return strlist->list[index];
}
 
/*
 * 判断字符串列表strlist内是否包含了字符串str。
 */
int strlist_contains(st_strlist *strlist, char* str)
{
    int i;
    for(i=0; i<strlist->size; i++){
        if(0 == (strcmp(strlist->list[i], str))){
            return 1;
        }
    }
    return 0;
}
 
/*
 * 释放字符串列表占用的内存空间
 */
int strlist_free(st_strlist *strlist)
{
    int i;
    if(!strlist){
        return -1;
    }
    for(i=0; i<strlist->size; i++){
        free(strlist->list[i]);
    }
    free(strlist->list);
    free(strlist);
    return 0;
}
 
/*
 * 打印字符串列表的相关信息
 */
void strlist_infolog(st_strlist *strlist)
{
    int i;
    printf("\n>>>\n");
    printf("strlist info:\n");
    printf("strlist size: %d\n", strlist->size);
    for(i=0; i<strlist->size; i++){
        printf("%d, %s\n",i, strlist->list[i]);
    }
}
 
int strlist_test()
{
 
    printf("hello c_strlist!");
 
    st_strlist *strlist = strlist_malloc();
 
    strlist_infolog(strlist);
 
    strlist_add(strlist,(char*)"aaaa");
    strlist_infolog(strlist);
 
    strlist_add(strlist,(char*)"bbbb");
    strlist_infolog(strlist);
 
    strlist_add(strlist,(char*)"字符串列表测试");
    strlist_infolog(strlist);
 
    strlist_insertAfter(strlist, (char*)"ccccc", 1);
    strlist_infolog(strlist);
 
    printf("\nis strlist contians \"123\"?  %d\n",
           strlist_contains(strlist,(char*)"123"));
 
    printf("\nis strlist contians \"字符串列表测试\" ? %d\n",
           strlist_contains(strlist,(char*)"字符串列表测试"));
 
    strlist_removeLast(strlist);
    strlist_infolog(strlist);
 
    printf("\nis strlist contians \"字符串列表测试\" ? %d\n",
           strlist_contains(strlist,(char*)"字符串列表测试"));
 
    strlist_removeAt(strlist,1);
    strlist_infolog(strlist);
 
 
    strlist_free(strlist);
 
    return 0;
}
 
 

 

void web_process_login(fcgxEnvParams *envParams,char *recvBuf,int len)
{
    char username[QUERY_STRING_VALUE_MAX_LEN] = {0};
    char password[QUERY_STRING_VALUE_MAX_LEN] = {0};
    struct json_object *json = NULL;
    struct json_object *username_obj = NULL;
    struct json_object *password_obj = NULL;

    // 解析JSON请求体
    json = json_tokener_parse(recvBuf);
    if (json == NULL) {
        log_error("Failed to parse JSON request");
        web_respone_err(envParams->req, WEB_STATUE_STR_400);
        return;
    }

    // 提取username和password字段
    if (!json_object_object_get_ex(json, "username", &username_obj) ||
        !json_object_object_get_ex(json, "password", &password_obj)) {
        log_error("Missing username or password in JSON request");
        json_object_put(json);
        web_respone_err(envParams->req, WEB_STATUE_STR_400);
        return;
    }

    // 获取字段值
    const char *username_str = json_object_get_string(username_obj);
    const char *password_str = json_object_get_string(password_obj);
    
    if (username_str == NULL || password_str == NULL) {
        log_error("Username or password is NULL");
        json_object_put(json);
        web_respone_err(envParams->req, WEB_STATUE_STR_400);
        return;
    }

    // 复制到本地缓冲区
    strncpy(username, username_str, QUERY_STRING_VALUE_MAX_LEN - 1);
    strncpy(password, password_str, QUERY_STRING_VALUE_MAX_LEN - 1);
    
    json_object_put(json); // 释放JSON对象

    // 验证字段是否为空
    if (strlen(username) == 0 || strlen(password) == 0) {
        web_respone_err(envParams->req, WEB_STATUE_STR_400);
        return;
    }
    if (VERITY_USER_RT_OK == web_cmd_verity_user(username,password)) {
        struct json_object *infor_object = NULL;
        struct json_object *data_object = NULL;
        infor_object = json_object_new_object();
        data_object = json_object_new_object();
        if (NULL == infor_object || NULL == data_object)
        {
            if (infor_object) json_object_put(infor_object);
            if (data_object) json_object_put(data_object);
            log_info("new json object failed.\n");
            web_respone_err(envParams->req,WEB_STATUE_STR_404);
            return;
        }
        
        // 构建data对象
        json_object_object_add(data_object, "token", json_object_new_string("token_placeholder")); // 实际中应该生成真实token
        json_object_object_add(data_object, "username", json_object_new_string(username));
        json_object_object_add(data_object, "lastLogin", json_object_new_string("2024-01-17T10:00:00Z")); // 实际中应该是当前时间
        json_object_object_add(data_object, "apiVersion", json_object_new_string("v1"));

        // 构建响应对象
        json_object_object_add(infor_object, "code", json_object_new_int(0));
        json_object_object_add(infor_object, "message", json_object_new_string("Login successful"));
        json_object_object_add(infor_object, "data", data_object);

        web_respone_json(envParams->req,infor_object);
        json_object_put(infor_object); // 这会自动释放data_object
    } else {
        web_respone_err(envParams->req,WEB_STATUE_STR_404);
    }

    
}